#include "session.h"

#include <stdio.h>
#include <stdlib.h>

#include "xmalloc.h"
#include "hashmap.h"
#include "base64.h"
#include "utils.h"

#define SES_COOKIE "sid"
#define SID_KEYLEN 48
static map_t *sessions;


static char *
new_session_key(void)
{
  char *result;

  result = (char *) ncmalloc(SID_KEYLEN+1, sizeof(char));
  gen_random_str(&result, SID_KEYLEN);
  Base64Encode(result, result, SID_KEYLEN);
  return (result);
}

static session_t *
new_session(void) {
  session_t *s = ncmalloc(1, sizeof(session_t));

  s->authed = false;
  s->firstRequest = true;
  s->sidPtr = new_session_key();
  s->str_IP = NULL;
  DD("new session: %s", s->sidPtr);
  hashmap_put(sessions, s->sidPtr, (any_t) s);
  return (s);
}

session_t *
get_session(const char *sid)
{
  session_t *ses = NULL;

  if (!sid) {
    return (new_session());
  }

  switch (hashmap_get(sessions, (char *)sid, (any_t *) &ses)) {
    case MAP_MISSING:
      return (new_session());
    case MAP_OK:
      DD("session: %s", ses->sidPtr);
      ses->firstRequest = false;
      return (ses);
      break;
    case MAP_FULL:
      break;
    case MAP_OMEM:
      break;
  }
  return (NULL);
}

session_t *
get_session_from_cookie(ck_map_t *cookies)
{
  session_t *s;
  cookie_obj_t *c = NULL;

  cookie_map_get(cookies, SES_COOKIE, &c);
  if (c) {
    s = get_session(c->val);
  } else {
    s = get_session(NULL);
  }
  return (s);
}

void
check_session(session_t *ses, ck_map_t *send_cookies)
{
  if (ses->firstRequest) {
    insert_cookie(send_cookies, SES_COOKIE, ses->sidPtr);
  }
}

void
init_sessionmgr(void)
{
  sessions = hashmap_new();
}

void
free_sessionmgr(void)
{
  int idx = 0;
  session_t *s = NULL;

  while (hashmap_iterate_all(sessions, &idx, NULL, (any_t *)&s)) {
    if (!s) continue;
    ncfree(s->sidPtr, SID_KEYLEN+1*sizeof(char));
    ncfree(s, sizeof(session_t));
  }
  hashmap_free(sessions);
}

